<?php

    /**
     * This file is part of the Intelligencer package.
     * For the full copyright and license, please view the LICENSE
     * file that was distributed with this source code.
     * 
     * @author      drapeko <roman.drapeko@gmail.com>
     * @copyright   Roman Drapeko <roman.drapeko@gmail.com>, 2009 - present
     */

    /**
     * Persistent cache stores data in array in PHP file. It's very fast because it's PHP.
     * @author drapeko
     */
    class itPersistentCache extends itCache {
        protected $cache = array();
        protected $filePath = null;
        
        protected $virgin = true;
        protected $localCache = null;
        
        const CACHE_ARRAY = 'cache';
        
        /**
         * Requires the path to the cache file. If the file does not exist it will be created.
         * @param string $filePath
         */
        public function __construct($filePath) {
            $this->localCache = new itLocalCache();
            
            $this->filePath = $filePath;
            if ($this->exists()) {
                $this->virgin = false;
                $this->read();
            }
        }
        
        /**
         * (non-PHPdoc)
         * @see Intelligencer/LibUtil/Cache/itCache#set($key, $value)
         */
        public function set($key, $val) {
            if (!is_object($val) || !($val instanceof itPersistentCacheableI)) {
                throw new itParameterException('PersistentCacheableI is accepted only');
            }
            
            $this->cache[$key] = array(
                get_class($val),
                $val->toPersistentCache()
            );
            
            $this->localCache->set($key, $val);
            $this->save();
            $this->virgin = false;
        }
        
        /**
         * (non-PHPdoc)
         * @see Intelligencer/LibUtil/Cache/itCache#get($key)
         */
        public function get($key) {
            $val = $this->localCache->get($key);
            if ($val != null) {
                return $val;
            }
            
            if (array_key_exists($key, $this->cache)) {
                $cached = $this->cache[$key];
                $val = new $cached[0]();
                $val->fromPersistentCache($cached[1]);
                $this->localCache->set($key, $val);
                
                return $val;
            }
            
            return null;
        }
        
        /**
         * (non-PHPdoc)
         * @see Intelligencer/LibUtil/Cache/itCache#del($key)
         */
        public function del($key) {
            $this->localCache->del($key);
            if (array_key_exists($key, $this->cache)) {
                unset($this->cache[$key]);
            }
            $this->save();
        }
        
        /**
         * (non-PHPdoc)
         * @see Intelligencer/LibUtil/Cache/itCache#clear()
         */
        public function clear() {
            $this->localCache->clear();
            $this->cache = array();
            $this->virgin = true;
            unlink($this->filePath);
        }
        
        /**
         * (non-PHPdoc)
         * @see Intelligencer/LibUtil/Cache/itCache#virgin()
         */
        public function virgin() {
            return $this->virgin;
        }
        
        protected function save() {
            $content = "<?php \n\n"
                ."\$".self::CACHE_ARRAY
                .' = '.stripslashes(var_export($this->cache, true)).';'
                ."\n?>";
                
            return file_put_contents($this->filePath, $content);
        }
        
        protected function exists() {
            return is_file($this->filePath) && is_readable($this->filePath);
        }
        
        protected function read() {
            include_once($this->filePath);
            
            if (isset(${self::CACHE_ARRAY})) {
                $this->cache = $cache;
            }
        }
    }
    
?>